import React, { useEffect, useMemo } from 'react';
import { NodeProps } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import { t } from '@/locales/i18n';
import {
  FlowNodeOutputTypeEnum,
  NodeInputKeyEnum,
  NodeOutputKeyEnum,
  WorkflowIOValueTypeEnum,
} from '@/types/workflow/constant';
import { FlowNodeItemType } from '@/types/workflow/node';

import { WorkflowContext } from '../../../context';
import NodeCard from '../render/NodeCard';

const typeMap = {
  [WorkflowIOValueTypeEnum.arrayString]: WorkflowIOValueTypeEnum.string,
  [WorkflowIOValueTypeEnum.arrayNumber]: WorkflowIOValueTypeEnum.number,
  [WorkflowIOValueTypeEnum.arrayBoolean]: WorkflowIOValueTypeEnum.boolean,
  [WorkflowIOValueTypeEnum.arrayObject]: WorkflowIOValueTypeEnum.object,
  [WorkflowIOValueTypeEnum.arrayAny]: WorkflowIOValueTypeEnum.any,
};

const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
  const { nodeId } = data;
  const { nodeList, onChangeNode } = useContextSelector(WorkflowContext, (v) => v);

  const loopStartNode = useMemo(
    () => nodeList.find((node) => node.nodeId === nodeId),
    [nodeList, nodeId],
  );

  const parentNode = useMemo(
    () => nodeList.find((node) => node.nodeId === loopStartNode?.parentNodeId),
    [nodeList, loopStartNode],
  );

  // According to the variable referenced by parentInput, find the output of the corresponding node and take its output valueType
  const loopItemInputType = useMemo(() => {
    const parentArrayInput = parentNode?.inputs.find(
      (input) => input.key === NodeInputKeyEnum.loopInputArray,
    );
    return parentArrayInput?.value
      ? (nodeList
          .find((node) => node.nodeId === parentArrayInput?.value[0])
          ?.outputs.find((output) => output.id === parentArrayInput?.value[1])
          ?.valueType as keyof typeof typeMap)
      : undefined;
  }, [parentNode, nodeList]);

  // Auth update loopStartInput output
  useEffect(() => {
    const loopArrayOutput = loopStartNode?.outputs.find(
      (output) => output.key === NodeOutputKeyEnum.loopStartInput,
    );

    // if loopItemInputType is undefined, delete loopStartInput output
    if (!loopItemInputType && loopArrayOutput) {
      onChangeNode({
        nodeId,
        type: 'delOutput',
        key: NodeOutputKeyEnum.loopStartInput,
      });
    }
    // if loopItemInputType is not undefined, and has no loopArrayOutput, add loopStartInput output
    if (loopItemInputType && !loopArrayOutput) {
      onChangeNode({
        nodeId,
        type: 'addOutput',
        value: {
          id: NodeOutputKeyEnum.loopStartInput,
          key: NodeOutputKeyEnum.loopStartInput,
          label: t('Array_element'),
          type: FlowNodeOutputTypeEnum.static,
          valueType: typeMap[loopItemInputType as keyof typeof typeMap],
        },
      });
    }
    // if loopItemInputType is not undefined, and has loopArrayOutput, update loopStartInput output
    if (loopItemInputType && loopArrayOutput) {
      onChangeNode({
        nodeId,
        type: 'updateOutput',
        key: NodeOutputKeyEnum.loopStartInput,
        value: {
          ...loopArrayOutput,
          valueType: typeMap[loopItemInputType as keyof typeof typeMap],
        },
      });
    }
  }, [loopStartNode?.outputs, nodeId, onChangeNode, loopItemInputType]);

  const Render = useMemo(() => {
    return (
      <NodeCard
        selected={selected}
        {...data}
        menuForbid={{
          copy: true,
          delete: true,
          debug: true,
        }}
      >
        {/* <div className="p-2">
          {!loopItemInputType ? (
            <Empty fontText={t('loop_start_tip')} className="mt-4 py-0" />
          ) : (
            <div className="overflow-hidden">
              <div className="grid grid-cols-2 grid-rows-2 gap-2 p-2">
                <div>{t('Variable_name')}</div>
                <div>{t('core.workflow.Value type')}</div>
                <div>{t('Array_element')}</div>
                <div>{typeMap[loopItemInputType]}</div>
              </div>
            </div>
          )}
        </div> */}
      </NodeCard>
    );
  }, [data, selected]);

  return Render;
};

export default React.memo(NodeLoopStart);
